﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Bearinglib;
using System.Reflection;
using System.Runtime.InteropServices;

using Excel = Microsoft.Office.Interop.Excel; 

namespace OfficeUtilities
{

    public class Com<T> : IDisposable where T : class
    {
        public T Instance { get; private set; }

        public Com(T comObject)
        {
            Instance = comObject;
        }

        public void Dispose()
        {
            if (Instance != null)
            {
                Marshal.ReleaseComObject(Instance);
                Instance = null;
            }
        }
    }

    public class BearingLibImportformExcel
    {
        private static void FinalReleaseAnyComObject(object o)
        {
            Marshal.FinalReleaseComObject(o);
            o = null;
        }

        public bool GetBearingDataFromFile(Bearinglib.IBearingType bearingType, String file_name)
        {
            object m = Type.Missing;

            using (var excelApp = new Com<Excel.Application>(new Excel.Application()))
            {
                //excelApp.Instance.Visible = true;
                using (var wbs = new Com<Excel.Workbooks>(excelApp.Instance.Workbooks))
                {
                   
                    using (var wb = new Com<Excel.Workbook>
                                (
                                     wbs.Instance.Open(
                                                    file_name,      //CorruptLoad 可选 Variant String 类型。要打开的工作簿的文件名。 
                                                    m,              //UpdateLinks 可选 Variant 指定更新文件中链接的方式。如果省略此参数，则提示用户指定链接的更新方式。有关此参数值的详细信息，请参阅“备注”部分。如果 Microsoft Excel 正在打开 WKS、WK1 或 WK3 格式的文件并且 UpdateLinks 参数为 2，则 Microsoft Excel 根据与该文件关联的图形生成图表。如果此参数为 0，则不创建任何图表。 
                                                    true,           //ReadOnly 可选 Variant 如果为 True，则以只读模式打开工作簿。 
                                                    m,              //Format 可选 Variant 如果 Microsoft Excel 正在打开文本文件，则由此参数指定分隔符。如果省略此参数，则使用当前的分隔符。有关此参数值的详细信息，请参阅“备注”部分。 
                                                    m,                  //Password 可选 Variant 一个字符串，包含打开受保护工作簿所需的密码。如果省略此参数并且工作簿已设置密码，则提示用户输入密码。 
                                                    m,                  //WriteResPassword 可选 Variant 一个字符串，包含写入受保护工作簿所需的密码。如果省略此参数并且工作簿已设置密码，则提示用户输入密码。 
                                                    m,                  //IgnoreReadOnlyRecommended 可选 Variant 如果为 True，则不让 Microsoft Excel 显示只读的建议消息（如果该工作簿以“建议只读”选项保存）。 
                                                    m,      //Origin 可选 Variant 如果该文件为文本文件，则此参数用于指示该文件来源于何种操作系统（以便正确映射代码页和回车/换行符 (CR/LF)）。可为以下 XlPlatform 常量之一：xlMacintosh、xlWindows 或 xlMSDOS。如果省略此参数，则使用当前操作系统。 
                                                    m,      //Delimiter 可选 Variant 如果该文件为文本文件并且 Format 参数为 6，则此参数是一个字符串，指定用作分隔符的字符。例如，可使用 Chr(9) 代表制表符，使用“,”代表逗号，使用“;”代表分号，或者使用自定义字符。只使用字符串的第一个字符。 
                                                    m,      //Editable 可选 Variant 如果文件为 Microsoft Excel 4.0 加载宏，则此参数为 True 时可打开该加载宏以使其在窗口中可见。如果此参数为 False 或被省略，则以隐藏方式打开加载宏，并且无法设为可见。本选项不能应用于由 Microsoft Excel 5.0 或更高版本的 Microsoft Excel 创建的加载宏。如果文件是 Excel 模板，则参数值为 True 时，会打开指定模板进行编辑。参数值为 False 时，可根据指定模板打开新的工作簿。默认值为 False。 
                                                    m,      //Notify 可选 Variant 当文件不能以可读写模式打开时，如果此参数为 True，则可将该文件添加到文件通知列表。Microsoft Excel 将以只读模式打开该文件并轮询文件通知列表，并在文件可用时向用户发出通知。如果此参数为 False 或被省略，则不请求任何通知，并且不能打开任何不可用的文件。 
                                                    m,      //Converter 可选 Variant 打开文件时试用的第一个文件转换器的索引。首先试用的是指定的文件转换器；如果该转换器不能识别此文件，则试用所有其他转换器。转换器索引由 FileConverters 属性返回的转换器行号组成。 
                                                    m,      //AddToMru 可选 Variant 如果为 True，则将该工作簿添加到最近使用的文件列表中。默认值为 False。 
                                                    m,      //Local 可选 Variant 如果为 True，则以 Microsoft Excel（包括控制面板设置）的语言保存文件。如果为 False（默认值），则以 Visual Basic for Applications (VBA) （Visual Basic for Applications (VBA)：Microsoft Visual Basic 的宏语言版本，用于编写基于 Microsoft Windows 的应用程序，内置于多个 Microsoft 程序中。） 的语言保存文件，其中 Visual Basic for Applications (VBA) 通常为美国英语版本，除非从中运行 Workbooks.Open 的 VBA 项目是旧的已国际化的 XL5/95 VBA 项目。 
                                                    m       //CorruptLoad 可选 Variant 
                                    )
                                )
                            )
                    {


                        Excel.Sheets excelSheets = wb.Instance.Worksheets;

                        string indexSheetname = bearingType.name;
                        Excel.Worksheet indexSheet1 = (Excel.Worksheet)excelSheets.get_Item(indexSheetname);

                        Excel.Range pRange = indexSheet1.UsedRange;


                        int Rowcount = pRange.Rows.Count;
                        int ColumnCount = pRange.Columns.Count;

                        Dictionary<int, IParam> head_names = new Dictionary<int, IParam>();

                        IParamlist param_list = bearingType.paramls;


                        for (int i = 2; i <= ColumnCount; i++)
                        {
                            Excel.Range temptitle = (Excel.Range)pRange.Cells[1, i];
                            String temptitleStr = Convert.ToString(temptitle.Value2);
                            Excel.Range tempname = (Excel.Range)pRange.Cells[2, i];
                            String tempnameStr = Convert.ToString(tempname.Value2);
                            if (tempnameStr == "")
                                continue;
                            IParam r = param_list.findByName(tempnameStr);
                            if (r == null)
                            {
                                r = bearingType.insertParam(tempnameStr, paramtype.t_string);
                                r.title = temptitleStr;
                                //BearinglibItem dr = r as BearinglibItem;
                                //dr.db_write();
                            }
                            head_names.Add(i, r);
                        }

                        for (int i = 3; i <= Rowcount; i++)
                        {

                            Excel.Range tempRange = (Excel.Range)pRange.Cells[i, 1];
                            String bearingName = Convert.ToString(tempRange.Value2);

                            Ibearing abearing = bearingType.bearingls.find(bearingName);
                            if (abearing == null)
                            {
                                abearing = bearingType.insertBearing(bearingName);
                            }

                           
                             for (int j = 2; j <= ColumnCount; j++)
                             {
                                 IParam ap = null;
                                 bool rt = head_names.TryGetValue(j, out  ap);
                                 if (rt == false)
                                     continue;

                                 Excel.Range tempDataRange = (Excel.Range)pRange.Cells[i, j];
                                 Object ParamValue = tempDataRange.Value2;
                                 if (ParamValue == null)
                                 {
                                     IParamValue pv = abearing.GetValue(ap);
                                     if (pv != null)
                                         abearing.deleteValue(pv);

                                     continue;
                                 }

                                 string va = Convert.ToString(ParamValue);
                                 abearing.SetValue(ap, va);  
                                 
                             }

                        }
                        
                        wb.Instance.Close(false, Type.Missing, Type.Missing);
                    }
  
                }
                excelApp.Instance.Quit();

            }

           
       
        

            return true;
        }
    }
}
